package runtime_area

// 虚拟机栈，主要参数有最大栈深度，当前栈深度，和指向栈顶元素的指针
type Stack struct {
	maxSize uint
	size    uint
	_top    *Frame
}

// 新建一个虚拟机栈。虚拟机栈在线程创建时创建
func newStack(maxSize uint) *Stack {
	return &Stack{maxSize: maxSize}
}

// 向虚拟机栈中push一个栈帧
func (self *Stack) push(frame *Frame) {
	// 已经达到了最大栈深度
	if self.size >= self.maxSize {
		panic("java.lang.StackOverFlowError")
	}
	// 判断虚拟机栈当前是不是空的，要添加的栈帧如果不是虚拟机栈的第一个栈帧，则让前一个栈帧的下一个栈帧指向新的栈帧
	if !self.isEmpty() {
		frame.lower = self._top
	}
	// 指向栈顶栈帧的指针
	self._top = frame
	// 栈帧的size+1
	self.size++
}

// 从虚拟机栈中弹出一个栈帧
func (self *Stack) pop() *Frame {
	// 栈帧是空的，报错
	if self._top == nil {
		panic("jvm stack is empty")
	}
	// 栈顶栈帧
	top := self._top
	// 新的栈顶栈帧
	self._top = top.lower

	top.lower = nil
	// size-1
	self.size--
	return top
}

// 获取当前栈顶栈帧，但不弹出
func (self *Stack) top() *Frame {
	return self._top
}

// 判断虚拟机栈是否为空
func (self *Stack) isEmpty() bool{
	return self._top == nil
}
